#include "dir_op.h"

/*优化点：

恶意路径如'; DROP TABLE file_info; --会导致严重安全问题

// 使用MySQL预处理语句
MYSQL_STMT *stmt = mysql_stmt_init(mysql);
const char *query = "SELECT id FROM file_info WHERE username=? AND file_path=? AND type='DIR' AND is_del=0";

mysql_stmt_prepare(stmt, query, strlen(query));

// 绑定参数
MYSQL_BIND params[2];
memset(params, 0, sizeof(params));

params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = pUsrInfo->usr_name;
params[0].buffer_length = strlen(pUsrInfo->usr_name);

params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = temp_path;
params[1].buffer_length = strlen(temp_path);

mysql_stmt_bind_param(stmt, params);
mysql_stmt_execute(stmt);*/

int cmd_cd(UsrInfo_t *pUsrInfo, char *path, MYSQL *mysql,char *ret_msg,int msg_size){
    //临时栈
    pathStack_t temp_stack;
    pathStackInit(&temp_stack);
    //切路径（绝对还是相对）
    char *value = NULL;
    if(path[0] == '/' || path[0] == '~'){
        value = strtok(path + 1,"/");
    }
    else{
        copyStack(&pUsrInfo->pathStack, &temp_stack);
        value = strtok(path, "/");
    }
    //切剩余
    while (value) {
        if(strcmp(value, "..") == 0) {
                pathStackPop(&temp_stack);    //空了弹栈函数不执行所以无事发生
        }
        else if(strcmp(value, ".") == 0){
            //无事发生
        } 
        else{
            // 复制字符串内容
            char *dir_copy = strdup(value);
            if (!dir_copy) {
                perror("内存分配失败");
                return -1;
            }
            pathStackPush(&temp_stack, dir_copy);  //压栈
        }
        value = strtok(NULL, "/");  //继续切割
    }
    //弹栈到字符串
    char temp_path[1024] = {0};
    stack_output_path(&temp_stack,temp_path);

    //sql查询
    char query[2048] = {0};  //准备sql语句
    snprintf(query, sizeof(query),
    "SELECT id FROM file_info "
    "WHERE username = '%s' AND file_path = '%s' "
    "AND type = 'DIR' AND is_del = 0",
    pUsrInfo->usr_name, temp_path);

    if (mysql_query(mysql, query)) {
        printf("查询语句失败: %s\n", mysql_error(mysql));
        return -1;
    }

    //debug用
    MYSQL_RES *result = mysql_store_result(mysql);//准备MYSQL_RES
    if (!result) {
        printf("MYSQL_RES 失败！\n");//应该不会执行
        return -1;
    }

    MYSQL_ROW row = mysql_fetch_row(result);
    if (!row) {
        printf("目录不存在！\n");
        snprintf(ret_msg, msg_size, "目录不存在！\n");
        mysql_free_result(result);
        return -1;
    }
    printf("row = %s \n",row[0]);
    //到这里说明路径存在
    copyStack(&temp_stack, &pUsrInfo->pathStack); //存储当前存在路径
    snprintf(ret_msg,msg_size,"%s:",temp_path);
    mysql_free_result(result);
    return 0;
}

int cmd_pwd(UsrInfo_t *pUsrInfo, char *pwd){
    stack_output_path(&pUsrInfo->pathStack,pwd);
    return 0; 
}

int cmd_ls(UsrInfo_t *pUsrInfo,char *list, int list_size,MYSQL *mysql){
    char real_path[1024] = {0};
    stack_output_path(&pUsrInfo->pathStack,real_path);
    //查id
    char query[2048] = {0};
    snprintf(query, sizeof(query),
        "SELECT id FROM file_info "
        "WHERE username = '%s' "
        "AND file_path = '%s' "
        "AND type = 'DIR' "
        "AND is_del = 0",
        pUsrInfo->usr_name, real_path);
    
    if (mysql_query(mysql, query)) {
        printf("查询当前目录失败: %s\n", mysql_error(mysql));
        return -1;
    }
    
    MYSQL_RES *result = mysql_store_result(mysql);
    if (!result) {
        printf("dasdas\n");
        return -1;
    }
    
    MYSQL_ROW row = mysql_fetch_row(result);
    if (!row) {//应该不会发生
        mysql_free_result(result);
        printf("错误：当前目录 '%s' 不存在或已被删除\n", real_path);
        return -1;
    }
    
    int current_dir_id = atoi(row[0]);//得到id
    mysql_free_result(result);
    
    //查询
    snprintf(query, sizeof(query),
        "SELECT filename, type FROM file_info "
        "WHERE parent_id = %d "
        "AND is_del = 0 "
        "ORDER BY type DESC, filename",
        current_dir_id);
    
    if (mysql_query(mysql, query)) {
        printf("列出目录内容失败: %s\n", mysql_error(mysql));
        return -1;
    }
    
    result = mysql_store_result(mysql);
    if (!result) {
        printf("获取结果失败！\n");
        return -1;
    }
    
    //输出结果
    char output[4096] = {0};  // 临时缓冲区
    char *ptr = output; //记录偏移
    int remaining = sizeof(output); //记录剩余大小防止溢出
    int count = 0;
    
    // 添加标题
    int written = snprintf(ptr, remaining, "当前目录 '%s' 内容：\n", real_path);//记录偏移
    if (written > 0) {
        ptr += written;
        remaining -= written;
    }

    while ((row = mysql_fetch_row(result)) && remaining > 10) {     //剩余10字节打印总结果
        const char *name = row[0];
        const char *type = row[1];
        
        // 格式化当前项
        char item[256];
        if (strcmp(type, "DIR") == 0) {
            snprintf(item, sizeof(item), "%s/", name); //目录
        } else {
            snprintf(item, sizeof(item), "%s", name);   //文件
        }
        
        // 添加到输出缓冲区
        if (count > 0) {
            // 添加分隔符（制表符或换行符）
            const char *separator = (count % 4 == 0) ? "\n" : "\t"; //4个一行
            written = snprintf(ptr, remaining, "%s", separator);
            if (written > 0) {
                ptr += written;
                remaining -= written;
            }
        }
        
        written = snprintf(ptr, remaining, "%s", item);
        if (written > 0) {
            ptr += written;
            remaining -= written;
        }
        
        count++;
    }
    
    // 添加结尾换行
    if (count > 0 && remaining > 1) {
        written = snprintf(ptr, remaining, "\n");
        if (written > 0) {
            ptr += written;
            remaining -= written;
        }
    }
    
    // 添加总结信息
    if (count == 0) {
        written = snprintf(ptr, remaining, "（空目录）\n");
    } else {
        written = snprintf(ptr, remaining, "共 %d 个项目\n", count);
    }
    
    if (written > 0) {
        ptr += written;
    }
    
    // 复制结果到输出缓冲区
    if (list && list_size > 0) {
        strncpy(list, output, list_size - 1);
        list[list_size - 1] = '\0';  // 确保以空字符结尾
    }
    
    mysql_free_result(result);
    return 0;
}

/*优化 mkdir 时候使用

int cmd_mkdir_helper(UsrInfo_t *pUsrInfo, char *path, MYSQL *mysql){
    //临时栈
    pathStack_t temp_stack;
    pathStackInit(&temp_stack);
    //切路径（绝对还是相对）
    char *value = NULL;
    if(path[0] == '/' || path[0] == '~'){
        value = strtok(path + 1,"/");
    }
    else{
        copyStack(&pUsrInfo->pathStack, &temp_stack);
        value = strtok(path, "/");
    }
    //切剩余
    while (value) {
        if(strcmp(value, "..") == 0) {
                pathStackPop(&temp_stack);      //空了弹栈函数不执行所以无事发生
        }
        else if(strcmp(value, ".") == 0){
            //无事发生
        } 
        else{
            // 复制字符串内容
            char *dir_copy = strdup(value);
            if (!dir_copy) {
                perror("内存分配失败");
                return -1;
            }
            pathStackPush(&temp_stack, dir_copy);  //压栈
        }
        value = strtok(NULL, "/");  //继续切割
    }
    //弹栈到字符串
    char temp_path[1024] = {0};
    stack_output_path(&temp_stack,temp_path);

    //sql查询
    char query[2048];  //准备sql语句
    snprintf(query, sizeof(query),
    "SELECT id FROM file_info "
    "WHERE username = '%s' AND file_path = '%s' "
    "AND type = 'DIR' AND is_del = 0",
    pUsrInfo->usr_name, temp_path);

    if (mysql_query(mysql, query)) {
        printf("查询失败: %s\n", mysql_error(mysql));
        return -1;
    }

    //debug用
    MYSQL_RES *result = mysql_store_result(mysql);//准备MYSQL_RES
    if (!result) {
        printf("MYSQL_RES 失败！\n");//应该不会执行
        return -1;
    }

    MYSQL_ROW row = mysql_fetch_row(result);
    if (!row) {
        printf("获取查询结果失败！\n");
        mysql_free_result(result);
        return -1;
    }
    printf("row = %s \n",row);
    //到这里说明路径存在

    return 0;
}

*/

//拼接dirname 判断是否存在 插入
int cmd_mkdir(UsrInfo_t pUsrInfo, const char *dirName,MYSQL *mysql,char *ret_msg,int msg_size){
    //找父节点id
    char real_path[1024] = {0};
    stack_output_path(&pUsrInfo.pathStack,real_path);
    char full_path[2048] = {0};
    if (strcmp(real_path, "/") == 0) {
        snprintf(full_path, sizeof(full_path), "/%s", dirName);
    }else{
        snprintf(full_path, sizeof(full_path), "%s/%s", real_path, dirName);
    }

    char query[4096] = {0};
    snprintf(query, sizeof(query),
        "SELECT id FROM file_info "
        "WHERE username = '%s' AND file_path = '%s' AND type = 'DIR' AND is_del = 0",
        pUsrInfo.usr_name, real_path);

    mysql_query(mysql, query);
    
    MYSQL_RES *parent_result = mysql_store_result(mysql);
    
    MYSQL_ROW parent_row = mysql_fetch_row(parent_result);
    
    int parent_id = atoi(parent_row[0]);
    mysql_free_result(parent_result);
    //判断
    memset(query, 0, sizeof(query)); 
    snprintf(query, sizeof(query),
    "SELECT id,is_del FROM file_info "
    "WHERE username = '%s' AND file_path = '%s'",
    pUsrInfo.usr_name, full_path);
    
    if (mysql_query(mysql, query)) {
        snprintf(ret_msg, msg_size, "目录检查失败: %s", mysql_error(mysql));
        return -1;
    }
    //debug用
    MYSQL_RES *result = mysql_store_result(mysql);

     if (result) {
        if (mysql_num_rows(result) > 0) {
            MYSQL_ROW row = mysql_fetch_row(result);
            int dir_id = atoi(row[0]);
            int is_del = atoi(row[1]); // 获取删除状态

            if (is_del == 0) {
                // 目录已存在且未删除
                snprintf(ret_msg, msg_size, "目录 '%s' 已存在", full_path);
                mysql_free_result(result);
                return -1;
            }
            else {
                // 目录存在但已删除
                mysql_free_result(result);
                // 更新记录恢复目录
                char update_query[4096];
                snprintf(update_query, sizeof(update_query),
                    "UPDATE file_info SET "
                    "is_del = 0, "         // 恢复为未删除
                    "recv_flag = 'DONE', "  // 更新状态
                    "parent_id = %d "       // 更新父目录ID
                    "WHERE id = %d",
                    parent_id, dir_id);
                if (mysql_query(mysql, update_query)) {
                    snprintf(ret_msg, msg_size, "创建目录失败: %s", mysql_error(mysql));
                    mysql_free_result(result);
                    return -1;
                }
                printf("目录 '%s' 创建成功\n", full_path);
                snprintf(ret_msg,msg_size,"目录 '%s' 创建成功\n", full_path);
                return 0;
            }
        }
        mysql_free_result(result);
    }

    //目录不存在，插入
    char insert_query[4096];
    snprintf(insert_query, sizeof(insert_query),
        "INSERT INTO file_info "
        "(filename, username, parent_id, file_path, type, recv_flag) "
        "VALUES ('%s', '%s', %d, '%s', 'DIR', 'DONE')",
        dirName,pUsrInfo.usr_name,parent_id,full_path);

    if (mysql_query(mysql, insert_query)) {
        snprintf(ret_msg, msg_size, "创建目录失败: %s", mysql_error(mysql));
        return -1;
    }


    printf("目录 '%s' 创建成功\n", full_path);
    snprintf(ret_msg,msg_size,"目录 '%s' 创建成功\n", full_path);
    return 0; 
}

int cmd_rmdir(UsrInfo_t pUsrInfo, const char *dirName,MYSQL *mysql,char *ret_msg,int msg_size){
    //拼接
    char real_path[1024] = {0};
    stack_output_path(&pUsrInfo.pathStack,real_path);
    char full_path[2048] = {0};
    if (strcmp(real_path, "/") == 0) {
        snprintf(full_path, sizeof(full_path), "/%s", dirName);
    } else {
        snprintf(full_path, sizeof(full_path), "%s/%s", real_path, dirName);
    }
    //找id
    char query[4096] = {0};
    snprintf(query, sizeof(query),
        "SELECT id FROM file_info "
        "WHERE username = '%s' AND file_path = '%s' "
        "AND type = 'DIR' "
        "AND is_del = 0",
    pUsrInfo.usr_name, full_path);

    if (mysql_query(mysql, query)) {
        printf("查询语句有问题: %s\n", mysql_error(mysql));
        return -1;
    }
    //debug用
    MYSQL_RES *result = mysql_store_result(mysql);//准备MYSQL_RES
    if (!result) {
        printf("MYSQL_RES 失败！\n");//应该不会执行
        mysql_free_result(result);
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    if (!row) {
        mysql_free_result(result);
        printf("错误：目录 '%s' 不存在、不是目录或已被删除\n", full_path);
        snprintf(ret_msg,msg_size,"错误：目录 '%s' 不存在、不是目录或已被删除\n", full_path);
        return -1;
    }

    int dir_id = atoi(row[0]);
    mysql_free_result(result);
    
    //找孩子    用count统计
    snprintf(query, sizeof(query),
        "SELECT COUNT(*) FROM file_info "
        "WHERE parent_id = %d "
        "AND is_del = 0",
        dir_id);
    
    if (mysql_query(mysql, query)) {
        printf("检查目录是否为空失败: %s\n", mysql_error(mysql));
        return -1;
    }
    
    result = mysql_store_result(mysql);
    if (!result) {
        printf("获取检查结果失败\n");
        return -1;
    }
    
    row = mysql_fetch_row(result);
    int child_count = row ? atoi(row[0]) : 0;
    mysql_free_result(result);
    
    if (child_count > 0) {
        printf("错误：目录 '%s' 非空，包含 %d 个文件/目录\n", full_path, child_count);
        snprintf(ret_msg,msg_size,"错误：目录 '%s' 非空，包含 %d 个文件/目录\n", full_path, child_count);
        return -1;
    }
    
    // 删除（标记为已删除）
    snprintf(query, sizeof(query),
        "UPDATE file_info "
        "SET is_del = 1 "
        "WHERE id = %d",
        dir_id);
    
    if (mysql_query(mysql, query)) {
        printf("删除目录语句失败: %s\n", mysql_error(mysql));
        return -1;
    }
    
    printf("目录 '%s' 已删除\n", real_path);
    snprintf(ret_msg,msg_size,"目录 '%s' 已删除\n", real_path);
    return 0;
}